package com.example.shushiyunsst.fragment.main.home

import android.annotation.SuppressLint
import android.os.Bundle
import android.text.format.DateUtils
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.arch.core.executor.ArchTaskExecutor
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.alibaba.android.arouter.launcher.ARouter
import com.alibaba.fastjson.JSON
import com.alibaba.fastjson.JSONArray
import com.alibaba.fastjson.JSONObject
import com.chad.library.adapter.base.BaseQuickAdapter
import com.chad.library.adapter.base.listener.OnItemChildClickListener
import com.example.library_common.adapter.multi.AdapterViewItemViewClick
import com.example.library_common.adapter.multi.JssMultiItemViewHolder
import com.example.library_common.adapter.multi.JssNewMultipleAdapter
import com.example.library_common.album.utils.Utils
import com.example.library_common.base.LazyFragment
import com.example.library_common.bean.CommonBean
import com.example.library_common.bean.DataCacheModule
import com.example.library_common.bean.UpDataVersionBean
import com.example.library_common.cache.JssCacheManager
import com.example.library_common.global.AppGlobals
import com.example.library_common.networking.RestClient
import com.example.library_common.utils.PixUtils
import com.example.library_common.view.bottombar.BottomBorInfo
import com.example.shushiyunsst.BuildConfig
import com.example.shushiyunsst.MyApp
import com.example.shushiyunsst.R
import com.example.shushiyunsst.fragment.main.home.recycler.bean.*
import com.example.shushiyunsst.fragment.main.home.recycler.bean.advise_bean.AdviseH5Entity
import com.example.shushiyunsst.fragment.main.home.recycler.bean.advise_bean.AdviseImgEntity
import com.example.shushiyunsst.fragment.main.home.recycler.bean.advise_bean.AdviseVideoEntity
import com.example.shushiyunsst.fragment.main.home.recycler.provider.*
import com.example.shushiyunsst.fragment.main.home.recycler.provider.advise_provider.AdviseH5Provider
import com.example.shushiyunsst.fragment.main.home.recycler.provider.advise_provider.AdviseImgProvider
import com.example.shushiyunsst.fragment.main.home.recycler.provider.advise_provider.AdviseVideoProvider
import com.example.shushiyunsst.fragment.main.home.recycler.view.IPlayTarget
import com.example.shushiyunsst.fragment.main.home.recycler.view.PageListPlayDetector
import com.example.shushiyunsst.fragment.main.home.recycler.view.PageListPlayManager
import com.example.shushiyunsst.fragment.main.mine.child.UpDataVersionPop
import com.example.shushiyunsst.util.*
import com.example.shushiyunsst.util.extension.goneVerticalTranAnimation
import com.example.shushiyunsst.util.extension.visibleVerticalTranAnimation
import com.example.wallet.bean.TransferFeeBean
import com.example.wallet.db.BalanceInfoManager
import com.example.wallet.db.UserInfoManager
import com.lxj.xpopup.XPopup
import java.io.Serializable
import kotlin.math.abs


class HomeFragment : LazyFragment(), BottomBorInfo, AdapterViewItemViewClick<HomeEntity>,
    OnItemChildClickListener {

    companion object {

        const val LAST_CACHED_KEY = "HOME_FRAGMENT_LAST_CACHED_KEY"

        fun newInstance(): HomeFragment {
            val args = Bundle()

            val fragment = HomeFragment()
            fragment.arguments = args
            return fragment
        }
    }

    override fun getLayoutId() = R.layout.home_fragment_layout

    override var icon = R.drawable.ic_home

    override var title = R.string.first_page

    private lateinit var mSwipeRefreshLayout: SwipeRefreshLayout

    private lateinit var mRecyclerView: RecyclerView

    private var mAdapter: JssNewMultipleAdapter<HomeEntity>? = null

    private val downlist = "downList"

    private var aCachedTime: TextView? = null

    private val sysMessageList = "sysMessageList"

    private val function = "function"

    private val dataTypeMapper = mapOf(
        //顶部轮播图
        "topList" to BannerEntityWrapper::class.java,

        //新闻
        "newsList" to NotifyEntityWrapper::class.java,

        //功能区
        function to FunEntityWrapper::class.java,

        //中部图标
        "middleList" to MiddleImgEntityWrapper::class.java,

        //系统消息
        sysMessageList to MinerEntityWrapper::class.java,

        //低部轮播图
        downlist to AdviseEntityWrapper::class.java,

        //币种比率
        "indexTokenList" to CurrencyEntityWrapper::class.java,

        //商品
        "downShopList" to ShopListEntityWrapper::class.java
    )



    private val downListDataTypeMapper = mapOf(
        AdviseEntity.ADVISE_H5 to AdviseH5Entity::class.java,
        AdviseEntity.ADVISE_VIDEO to AdviseVideoEntity::class.java,
        AdviseEntity.ADVISE_IMG to AdviseImgEntity::class.java
    )

    private var mData = mutableListOf<HomeEntity>()


    private lateinit var mHeaderView: View

    private val homePageBannerHeight = PixUtils.dp2px(4)

    private var mDistance = 0

    private var isRequesting = false

    private var playDetector: PageListPlayDetector? = null

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        onSaveInCache()

    }

    private fun onSaveInCache() {
        val bean: CommonBean<List<HomeEntity>> = CommonBean<List<HomeEntity>>()
        bean.data = mAdapter?.data
        val dataCacheModule = DataCacheModule()

        val data: List<HomeEntity> = bean.data

        val beanList = dataCacheModule.beanList
        for (e in data) {
            beanList.add(e)
        }
        dataCacheModule.time = System.currentTimeMillis()
        JssCacheManager.savePersistence(LAST_CACHED_KEY, dataCacheModule)
    }

    override fun onViewStateRestored(savedInstanceState: Bundle?) {
        super.onViewStateRestored(savedInstanceState)
        onRestoredFormCache(false)
    }


    override fun initView(view: View) {

//        MediaControllerManager.get() // init exoplayer

        aCachedTime = view.findViewById(R.id.aCachedTime)

        mSuperBackPressedSupport = false

        mHeaderView = view.findViewById(R.id.mHeaderView)


        val userInfoWrapper = UserInfoManager.userInfoManager.getUserInfoWrapper()

        Log.d("initView", "initView: ${userInfoWrapper.toString()}")

        mSwipeRefreshLayout = view.findViewById(R.id.mSwipeRefreshLayout)

        mSwipeRefreshLayout.setProgressViewOffset(false, 0, PixUtils.dp2px(60))
        mSwipeRefreshLayout.setColorSchemeResources(R.color.nav_bar_bg_color)

        mSwipeRefreshLayout.setProgressBackgroundColorSchemeResource(R.color.colorAccent)

        mRecyclerView = view.findViewById(R.id.mRecyclerView)

        playDetector = PageListPlayDetector(this, mRecyclerView)

        mRecyclerView.setHasFixedSize(true)

        mRecyclerView.layoutManager =
            LinearLayoutManager(_mActivity, LinearLayoutManager.VERTICAL, false)

        mAdapter = object : JssNewMultipleAdapter<HomeEntity>(mData) {
            override fun onViewAttachedToWindow(holder: JssMultiItemViewHolder<*>) {
                super.onViewAttachedToWindow(holder)
                if (holder is AdviseVideoProvider) {
                    playDetector?.addTarget(holder.findAdviseVideoView() as IPlayTarget)
                }
            }

            override fun onViewDetachedFromWindow(holder: JssMultiItemViewHolder<*>) {
                super.onViewDetachedFromWindow(holder)
                if (holder is AdviseVideoProvider) {
                    playDetector?.removeTarget(holder.findAdviseVideoView() as IPlayTarget)
                }
            }
        }
//        mAdapter.animationEnable = true
//        mAdapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.ScaleIn)
//        mAdapter.isAnimationFirstOnly = false

        mRecyclerView.adapter = mAdapter

        mAdapter?.recyclerView = mRecyclerView

        mAdapter?.register(BannerEntityWrapper::class.java, BannerProvider::class.java)

        mAdapter?.register(NotifyEntityWrapper::class.java, NotifyProvider::class.java)

        mAdapter?.register(FunEntityWrapper::class.java, FunProvider::class.java)

        mAdapter?.register(MinerEntityWrapper::class.java, MinerProvider::class.java)

        mAdapter?.register(MiddleImgEntityWrapper::class.java, MiddleImgProvider::class.java)

//        mAdapter.register(AdviseEntityWrapper::class.java, AdviseProvider::class.java)

        mAdapter?.register(AdviseH5Entity::class.java, AdviseH5Provider::class.java)

        mAdapter?.register(AdviseImgEntity::class.java, AdviseImgProvider::class.java)

        mAdapter?.register(AdviseVideoEntity::class.java, AdviseVideoProvider::class.java)

        mAdapter?.register(CurrencyEntityWrapper::class.java, CurrencyProvider::class.java)

        mAdapter?.register(ShopListEntity::class.java, ShopListProvider::class.java)

        mAdapter?.lifecycle = lifecycle

        mAdapter?.lifecycleOwner = this

        mAdapter?.adapterViewItemViewClick = this

//        mAdapter.addChildClickViewIds(R.id.miner_provider_pick_up)

        mAdapter?.setOnItemChildClickListener(this)

        mSwipeRefreshLayout.setDistanceToTriggerSync(PixUtils.dp2px(70))
        mSwipeRefreshLayout.setOnRefreshListener {

            requestData()
        }

        if (!mSwipeRefreshLayout.isRefreshing) {

            mSwipeRefreshLayout.isRefreshing = true
        }

        mRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)

                mDistance += dy

                var alpha = abs(mDistance) * 1.0f / (homePageBannerHeight * 1.0f)
                alpha = if (alpha >= 1.0f) 1.0f else alpha

                mHeaderView.alpha = alpha

            }
        })
    }


    override fun refreshData() {

        if (!mSwipeRefreshLayout.isRefreshing && isSupportVisible) {

            mSwipeRefreshLayout.isRefreshing = true

            requestData()
        }


    }

    override fun lazyInit() {
        refreshData()
    }


    override fun onSupportVisible() {
        super.onSupportVisible()
        playDetector?.onResume()
        refreshData()
//        rootView?.postDelayed({
//        refreshData()
//        },1000)

    }


    override fun onSupportInvisible() {
        super.onSupportInvisible()
        playDetector?.onPause()
    }

    override fun onPause() {
        super.onPause()
        playDetector?.onPause()
    }

    override fun onDestroy() {
        super.onDestroy()
        //记得销毁
        PageListPlayManager.getInstance().release()
    }

    fun requestData() {
        if (isRequesting) {
            return
        }
        isRequesting = true

//        mAdapter.clears()

        playDetector?.onPause()

        val userInfo = UserInfoManager.userInfoManager.getUserInfoWrapper()?.userInfo
        val maps = mapOf(
            "uid" to userInfo?.uid,
            "sysWalletAddress" to userInfo?.sysWalletAddress
        )
        RestClient.builder()
            .url(R.string.appIndex)
            .raw(JSON.toJSONString(maps))
            .success {

                showData(it)

            }.failure {

//                mAdapter?.clears()
//
//                val obj = JSONObject()
//
//                val funList = getFunList()
//
//                obj[function] = JSON.toJSON(funList)
//
//                parserData(JSON.toJSONString(obj))

                onRestoredFormCache(true)

                checkAppVersion()

                isRequesting = false

                endRefresh()

            }.error { _, _ ->

//                mAdapter?.clears()
//
//                val obj = JSONObject()
//
//                val funList = getFunList()
//
//                obj[function] = JSON.toJSON(funList)
//
//                parserData(JSON.toJSONString(obj))

                onRestoredFormCache(true)

                checkAppVersion()

                isRequesting = false

                endRefresh()
            }
            .build()
            .post()

    }

    private fun showData(it: String?) {

        aCachedTime?.goneVerticalTranAnimation()

        mAdapter?.clears()

        //                mDistance = 0

        parserData(it)

        checkAppVersion()

        isRequesting = false

        endRefresh()

        onSaveInCache()
    }

    private fun onRestoredFormCache(isNetworkFailed: Boolean) {
        JssCacheManager.getCacheFromPersistence(
            LAST_CACHED_KEY,
            object : JssCacheManager.QueryListener22 {
                override fun onQuerySucceed(it: Any?) {
                    if (it is DataCacheModule) {
                        mAdapter?.clears()

                        val beanList: List<Serializable> = it.beanList

                        for (e in beanList) {

                            mAdapter?.addData(e as HomeEntity)

                        }
                        if (beanList.isNotEmpty()) {

                            setIsLoad(true)

                            if (isNetworkFailed) {
                                aCachedTime?.visibleVerticalTranAnimation()
                                aCachedTime?.setText(R.string.net_work_failed)
                            }

//                        aCachedTime?.text=DateUtils.formatElapsedTime(it.time)

                        } else {

                            onFormTempJsonStr()
                        }
                    }
                }

                override fun onQueryFailed() {
                    onFormTempJsonStr()
                }

            })
    }

    @SuppressLint("RestrictedApi")
    private fun onFormTempJsonStr() {
        ArchTaskExecutor.getIOThreadExecutor().execute {
            val homeDataMod =
                Utils.getJsonFromRaw(AppGlobals.getApplication(), R.raw.home_data_modle)
            ArchTaskExecutor.getMainThreadExecutor().execute {
                showData(homeDataMod)
            }
        }
    }

    private fun endRefresh() {
        if (mSwipeRefreshLayout.isRefreshing) {
            mSwipeRefreshLayout.postDelayed({
                mSwipeRefreshLayout.isRefreshing = false
            }, 1000L)
        }

    }

    private fun checkAppVersion() {

        if (MyApp.isAppUpData) return

        MyApp.isAppUpData = true

        val maps = mapOf(
            "version" to BuildConfig.VERSION_NAME
        )
        RestClient.builder()
            .url(R.string.updateAppVersion)
            .raw(JSON.toJSONString(maps))
            .success {

                val obj = JSON.parseObject(it, UpDataVersionBean::class.java)

                if (obj.needToUpData()) {
                    val flag = obj.version.isForce == 1
                    val pop = UpDataVersionPop(_mActivity)
                    pop.setVersionBean(obj)
                    pop.setTarget(this)
                    XPopup.Builder(_mActivity)
//                        .enableShowWhenAppBackground(true)
                        .dismissOnTouchOutside(!flag)
                        .dismissOnBackPressed(!flag)
                        .asCustom(pop)
                        .show()
                }

            }
            .error { _, _ ->
                MyApp.isAppUpData=false
            }
            .failure {
                MyApp.isAppUpData=false
            }
            .build()
            .post()

    }


    private fun parserData(it: String?) {

        val data = JSON.parse(it)

        if (data is JSONObject) {

            val sstTransferFee = data["sstTransferFee"].toString()

            val cmlTransferFee = data["cmlTransferFee"].toString()

            val transferFeeBean = TransferFeeBean(
                sstTransferFee,
                cmlTransferFee
            )

            BalanceInfoManager.mBalanceInfoManager.saveFeeBeanBean(transferFeeBean)

            val funList = getFunList()

            data.put(function, JSON.toJSON(funList))

            Log.d("parserData", "parserData: data==$data")

            for (e in dataTypeMapper.entries.iterator()) {

                val dataTypeValue = e.value

                val json = data[e.key]

                var clazz = hookGenericSuperClass(dataTypeValue)

                clazz = (clazz ?: dataTypeValue) as Class<*>

                val entityWrapper = dataTypeValue.newInstance()
                        as EntityWrapper<*>

//                Log.d("parserData", "parserData: key==${e.key}")
//                Log.d("parserData", "parserData: key==${entityWrapper.isFlatList}")

                if (json is JSONArray) {
//                    Log.d("parserData", "json: key==${ json.toString()}")
                    val array = JSON.parseArray(

                        json.toString(),

                        clazz
                    ) as MutableList<HomeEntity>

                    if (array.size > 0) {

                        entityWrapper.list = array


//                        Log.d("parserData", "array: $array")

                        when {
                            entityWrapper.isFlatList -> {
                                mAdapter?.addData(array)
                            }
                            downlist == e.key -> {

                                val arrayLs = reSettingDownList(array)

                                mAdapter?.addData(arrayLs)

                            }
                            else -> {
                                entityWrapper.setItemType(entityWrapper.itemType)

                                mAdapter?.addData(entityWrapper)
                            }
                        }

                    } else {
                        if (e.key == sysMessageList) {
                            entityWrapper.setItemType(entityWrapper.itemType)

                            mAdapter?.addData(entityWrapper)
                        }
                    }

                } else if (json is JSONObject) {
                    val obj = JSON.parseObject(
                        json.toJSONString(),
                        clazz
                    ) as HomeEntity

                    mAdapter?.addData(obj)
                }
            }
        }
    }

    private fun reSettingDownList(array: MutableList<HomeEntity>): MutableList<HomeEntity> {
        val ls = mutableListOf<HomeEntity>()
        for (e in array) {
            val bean = e as AdviseEntity
            val clazz = downListDataTypeMapper[bean.flag]
            Log.d("onCreateDefViewHolder", "reSettingDownList: ${bean.flag}")
            if (clazz != null) {
                val newBean = JSON.parseObject(JSON.toJSONString(e), clazz)
                ls.add(newBean)
            }
        }
        return ls
    }

    override fun onAdapterViewListItemViewClick(m: HomeEntity?, viewType: Int) {
        when (viewType) {
            HomeEntity.MIDDLE_IMG_TYPE -> {
                if (m is MiddleImgEntity) {

                    ARouter.getInstance()
                        .build(m.targetUrl)
                        .startNavigation(this)
                }
            }


            AdviseEntity.ADVISE_H5 -> {
                if (m is AdviseH5Entity) {

                    ARouter.getInstance()
                        .build(INCUBATOR)
                        .withString(WEB_URL, m.targetUrl)
                        .withString(WEB_TITLE, m.modName)
                        .startNavigation(this)
                }
            }
            HomeEntity.Notify_TYPE -> {
                ARouter.getInstance()
                    .build(MESSAGE_PAGE)
                    .startNavigation(this)
            }
            HomeEntity.FUN_TYPE -> {


                if (m !is FunEntity) {
                    return
                }
                if (m.pagUri.isNotEmpty()) {

                    if (m.pagUri == INCUBATOR) {
                        ARouter.getInstance()
                            .build(m.pagUri)
                            .startNavigationSelf(this)
                        return
                    }

                    ARouter.getInstance()
                        .build(m.pagUri)
                        .startNavigation(this)
                }

            }
            HomeEntity.DOWN_SHOP_LIST -> {

                if (m !is ShopListEntity) {
                    return
                }

                ARouter.getInstance()
                    .build(m.pageUri)
                    .withString(GOODS_ID, m.goodsId.toString())
                    .startNavigation(this)
            }
        }
    }

    override fun onItemChildClick(adapter: BaseQuickAdapter<*, *>, view: View, position: Int) {
        when (view.id) {
            R.id.miner_provider_pick_up -> {
                //摘取草莓
                ARouter.getInstance()
                    .build(MINER22)
                    .startNavigation(this)
            }
        }
    }


}